package com.weareint.xxljob.dynamic;

import com.weareint.xxljob.XxlJobInfo;
import com.weareint.xxljob.XxlJobUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.support.CronExpression;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

/**
 *
 *
 * <pre>
 *  注册器
 * </pre>
 *
 * @author johnny
 * @date 2021-08-19 9:56 上午
 */
@Slf4j
public class XxlJobDynamicRegister {

    private final XxlJobOperators xxlJobOperators;

    public XxlJobDynamicRegister(XxlJobOperators xxlJobOperators) {
        this.xxlJobOperators = xxlJobOperators;
    }

    public void register(BuildXxlJob buildXxlJob) {
        XxlJobInfo xxlJobInfo = buildXxlJob.build();
        if (xxlJobInfo != null) {
            try {
                CronExpression expression = CronExpression.parse(xxlJobInfo.getScheduleConf());
                LocalDateTime nextExecTime = expression.next(LocalDateTime.now());
                if (null != nextExecTime) {
                    log.info(
                            "{} XxlJOb 定时任务下次执行的时间为:[{}]",
                            xxlJobInfo.getExecutorHandler(),
                            nextExecTime.format(
                                    DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
                }
            } catch (Exception e) {
                log.error("【cron 解析错误: {}】", xxlJobInfo.getScheduleConf());
                return;
            }
            log.info("【dynamic register  xxlJob start】");
            xxlJobOperators.add(xxlJobInfo);
            log.info("【dynamic register  xxlJob end  】");
        }
    }

    public interface BuildXxlJob {

        /**
         * 填充 补全 xxlJob
         *
         * @param xxlJobInfo : xxlJobInfo
         * @return : XxlJobInfo
         */
        void fillXxlJobInfo(XxlJobInfo xxlJobInfo);

        /**
         * build
         *
         * @return :XxlJobInfo
         */
        default XxlJobInfo build() {
            XxlJobInfo xxlJobInfo = XxlJobUtils.defaultXxlJobInfo();
            fillXxlJobInfo(xxlJobInfo);
            return xxlJobInfo;
        }
    }
}
